package com.freight.tws.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.freight.common.core.constant.Constants;
import com.freight.common.core.constant.DictConstants;
import com.freight.common.core.constant.SmsConstants;
import com.freight.common.core.constant.WebsocketConstants;
import com.freight.common.core.exception.ServiceException;
import com.freight.common.core.utils.DateUtils;
import com.freight.common.core.utils.StringUtils;
import com.freight.common.redis.service.RedisService;
import com.freight.common.security.service.AppTokenService;
import com.freight.common.security.utils.SecurityUtils;
import com.freight.common.wlhyupload.WlhyUpload;
import com.freight.tws.api.domain.Driver;
import com.freight.tws.api.domain.PtQy;
import com.freight.tws.api.domain.Vehicle;
import com.freight.tws.api.model.LoginDriver;
import com.freight.tws.domain.TwsCompanyDriver;
import com.freight.tws.domain.TwsWarn;
import com.freight.tws.domain.vo.UpdatePasswordVo;
import com.freight.tws.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.freight.common.core.web.controller.BaseServiceImpl;
import com.freight.tws.mapper.DriverMapper;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 司机信息Service业务层处理
 *
 * @author ruoyi
 * @date 2022-01-20
 */
@Service
public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> implements IDriverService {

    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private ITwsCompanyDriverService twsCompanyDriverService;

    @Autowired
    private IVehicleService vehicleService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private AppTokenService appTokenService;

    @Autowired
    private ITwsNoticeService twsNoticeService;

    @Autowired
    private IPtQyService ptQyService;

    @Autowired
    private ITwsWarnService warnService;

    /**
     * 查询常用司机列表（tws_company_driver物流公司-司机关系表）
     * @param driver
     * @return
     */
    @Override
    public IPage<Driver> driverList(IPage<Driver> page, Driver driver) {
        return driverMapper.driverList(page, driver, DictConstants.DELETE_BASE.OK.getKey());
    }

    /**
     * 司机注册APP
     * @param driver
     * @return
     */
    @Override
    public boolean regist(Driver driver) {
        String password = StringUtils.isNotBlank(driver.getPassword()) ? driver.getPassword() : Constants.APP_PASSWORD;
        driver.setPassword(SecurityUtils.encryptPassword(password));
        driver.setIsCert(DictConstants.IS_CERT.WRZ.getKey());
        driver.setState(DictConstants.COMMON_STATE.OK.getKey());
        driver.setIsSendToPro(DictConstants.IS_SEND_TO_PRO.WSC.getKey());
        return this.save(driver);
    }

    /**
     * 忘记密码 修改密码（需要短信验证码）
     * @param updatePasswordVo
     */
    @Override
    public int forgetUpdatePassword(UpdatePasswordVo updatePasswordVo) {
        if(StringUtils.isBlank(updatePasswordVo.getPhone())) {
            throw new ServiceException("手机号不能为空");
        }
        // 判断验证码是否正确
        String verifyCode = redisService.getCacheObject(SmsConstants.CACHE_SMS_VERFY_CODE + updatePasswordVo.getPhone());
        if(verifyCode == null) {
            throw new ServiceException("验证码已过期");
        }
        if(!verifyCode.equals(updatePasswordVo.getCode())) {
            throw new ServiceException("验证码错误");
        }

        Driver driver = driverMapper.selectOne(new LambdaQueryWrapper<Driver>().eq(Driver::getTelephone, updatePasswordVo.getPhone()));
        if(driver == null) {
            throw new ServiceException("用户不存在");
        }
        driver.setPassword(SecurityUtils.encryptPassword(updatePasswordVo.getNewPassword()));
        return driverMapper.updateById(driver);
    }

    /**
     * 修改密码（需要旧密码）
     * @param updatePasswordVo
     */
    @Override
    public int resetPassword(UpdatePasswordVo updatePasswordVo) {
        if(StringUtils.isBlank(updatePasswordVo.getPhone()) || StringUtils.isBlank(updatePasswordVo.getOldPassword()) || StringUtils.isBlank(updatePasswordVo.getNewPassword())) {
            throw new ServiceException("手机号/密码不能为空");
        }
        Driver driver = driverMapper.selectOne(new LambdaQueryWrapper<Driver>().eq(Driver::getTelephone, updatePasswordVo.getPhone()));
        if(driver == null) {
            throw new ServiceException("用户不存在");
        }
        if(!SecurityUtils.matchesPassword(updatePasswordVo.getOldPassword(), driver.getPassword())) {
            throw new ServiceException("旧密码不正确");
        }
        driver.setPassword(SecurityUtils.encryptPassword(updatePasswordVo.getNewPassword()));
        return driverMapper.updateById(driver);
    }

    /**
     * 提交实名认证
     */
    @Override
    public int toCert(HttpServletRequest request, Driver driver) {
        // 助记码
//        driver.setCode(PinYinUtils.toFirstPinYin(driver.getDriverName()));
        // 实名状态：未实名 -> 审核中
        driver.setIsCert(DictConstants.IS_CERT.SHZ.getKey());
        int i = driverMapper.updateById(driver);
        // 更新缓存
        LoginDriver loginDriver = appTokenService.getLoginUser(request);
        if(loginDriver != null) {
            // 实名状态设置为审核中
            loginDriver.getDriver().setIsCert(driver.getIsCert());
            appTokenService.refreshToken(loginDriver);
        }
        // 查询车辆
//        Integer integer = vehicleMapper.selectCount(new LambdaQueryWrapper<Vehicle>()
//                .eq(Vehicle::getDriverId, driver.getId())
//                .eq(Vehicle::getState, DictConstants.COMMON_STATE.OK.getKey()));
//        if(integer == 0) {
//            return R.ok(null, "提交成功，请前往绑定车辆...");
//        }
        // 保存到业务公告消息表（包含websocket通知）
        twsNoticeService.newTwsNotice("admin", WebsocketConstants.TWS_NOTICE_TYPE.CERT_DRIVER.getKey(), WebsocketConstants.TWS_NOTICE_TYPE.CERT_DRIVER.getName());
        return i;
    }

    /**
     * 司机审核
     * @param driver
     * @return
     */
    @Override
    @Transactional
    public int cert(Driver driver) {
        Driver byId = driverMapper.selectById(driver.getId());
        // 如果状态不是在审核中
        if(!DictConstants.IS_CERT.SHZ.getKey().equals(byId.getIsCert())) {
            throw new ServiceException("审核失败");
        }
        // 更新缓存
        LoginDriver loginDriver = appTokenService.getLoginUserByLoginId(String.valueOf(driver.getId()));
        if(loginDriver != null) {
            // 更新实名状态
            loginDriver.getDriver().setIsCert(driver.getIsCert());
            appTokenService.refreshToken(loginDriver);
        }
        // 审核通过
        if(DictConstants.IS_CERT.YRZ.getKey().equals(driver.getIsCert())) {
            // 保存到业务公告消息表（包含websocket通知）(司机的手机号即为登录用户名)
            twsNoticeService.newTwsNotice(byId.getTelephone(), WebsocketConstants.TWS_NOTICE_TYPE.CERT_DRIVER_PASS.getKey(), WebsocketConstants.TWS_NOTICE_TYPE.CERT_DRIVER_PASS.getName());
        } else if(DictConstants.IS_CERT.RZSB.getKey().equals(driver.getIsCert())) {
            // 保存到业务公告消息表（包含websocket通知）(司机的手机号即为登录用户名)
            twsNoticeService.newTwsNotice(byId.getTelephone(), WebsocketConstants.TWS_NOTICE_TYPE.CERT_DRIVER_FAIL.getKey(), WebsocketConstants.TWS_NOTICE_TYPE.CERT_DRIVER_FAIL.getName());
        }
        return driverMapper.updateById(driver);
    }

    /**
     * 司机禁/启用
     */
    @Override
    @Transactional
    public int stateChange(Driver driver) {
        Driver byId = driverMapper.selectById(driver.getId());
        if(byId.getState().equals(driver.getState())) {
            throw new ServiceException("操作失败");
        }
        return driverMapper.updateById(driver);
    }

    /**
     * 物流公司添加常用司机
     * @param driverId
     * @return
     */
    @Override
    public boolean add(Long driverId) {
        TwsCompanyDriver one = twsCompanyDriverService.getOne(new LambdaQueryWrapper<TwsCompanyDriver>()
                .eq(TwsCompanyDriver::getDriverId, driverId));
        if(one != null) {
            throw new ServiceException("已添加该司机");
        }
        TwsCompanyDriver companyDriver = new TwsCompanyDriver();
        companyDriver.setCompanyId(Long.valueOf(com.freight.common.core.utils.SecurityUtils.getTenantId()));
        companyDriver.setDriverId(driverId);
        return twsCompanyDriverService.save(companyDriver);
    }

    /**
     * 删除常用司机（tws_company_driver物流公司-司机关系表）
     */
    @Override
    public boolean removes(List<Long> driverIds) {
        return twsCompanyDriverService.removes(driverIds);
    }

    /**
     * 删除司机（tws_driver司机表）
     */
    @Override
    @Transactional
    public boolean delete(List<Long> driverIds) {
        boolean b = this.removeByIds(driverIds);
        // 删除物流公司-司机关系表
        boolean removes = twsCompanyDriverService.removes(driverIds);
        // 删除车辆
        boolean remove = vehicleService.remove(new LambdaQueryWrapper<Vehicle>()
                .in(Vehicle::getDriverId, driverIds));
        return b && removes && remove;
    }

    /**
     * 检测证件到期时间
     */
    @Override
    public void paperExpires() {
        // 3天后的时间
        Date date = DateUtils.addSubDay(3);
        // 到期时间小于3天后
        List<Driver> drivers = driverMapper.selectList(new LambdaQueryWrapper<Driver>()
                                    .le(Driver::getValidPeriodTo, date));
        if(drivers.size() > 0) {
            Date now = new Date();
            List<TwsWarn> list = new ArrayList<>();
            for (Driver driver : drivers) {
                TwsWarn warn = new TwsWarn();
                warn.setContent(StringUtils.format("司机【{}】的驾驶证{}，【{} ~ {}】",
                                            driver.getDriverName(),
                                            driver.getValidPeriodTo().before(now) ? "已过期" : "即将过期",
                                            DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, driver.getValidPeriodFrom()),
                                            DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, driver.getValidPeriodTo())));
                warn.setIsHandle("0");
                warn.setCreateTime(now);
                warn.setDelFlag(DictConstants.DELETE_BASE.OK.getKey());
                list.add(warn);
            }
            warnService.saveBatch(list);
            // 保存到业务公告消息表（包含websocket通知）
            twsNoticeService.newTwsNotice("admin", WebsocketConstants.TWS_NOTICE_TYPE.WARN_NEW.getKey(), WebsocketConstants.TWS_NOTICE_TYPE.WARN_NEW.getName());
        }
    }

    /**
     * 上传司机
     * @return
     */
    @Override
    public boolean upload(Long id) {
        // 平台信息
        PtQy ptQy = ptQyService.lists();
        Driver driver = driverMapper.selectById(id);
        if(driver != null) {
            if(!DictConstants.IS_SEND_TO_PRO.YSC.getKey().equals(driver.getIsSendToPro())) {
                if(DictConstants.IS_CERT.YRZ.getKey().equals(driver.getIsCert())) {
                    boolean b = WlhyUpload.wlhyUpload(ptQy, driver);
                    driver.setIsSendToPro(DictConstants.IS_SEND_TO_PRO.YSC.getKey());
                    int i = driverMapper.updateById(driver);
                    return b && i > 0;
                } else {
                    throw new ServiceException("司机未认证，不可上传");
                }
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

}
